/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(
    dead_code,
    mutable_transmutes,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut,
    clippy::never_loop
)]

use crate::common::*;

extern "C" {
    fn stat(path:*const libc::c_char,buf:*mut stat) -> libc::c_int;
    fn mkdir(__path: *const libc::c_char, __mode: __mode_t) -> libc::c_int;
    fn strchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char;
    fn chown(__file: *const libc::c_char, __owner: __uid_t, __group: __gid_t) -> libc::c_int;
    fn __errno_location() -> *mut libc::c_int;
    fn sudo_warn_nodebug_v1(fmt: *const libc::c_char, _: ...);
    fn sudo_warnx_nodebug_v1(fmt: *const libc::c_char, _: ...);
    fn sudo_debug_printf2_v1(
        func: *const libc::c_char,
        file: *const libc::c_char,
        line: libc::c_int,
        level: libc::c_int,
        fmt: *const libc::c_char,
        _: ...
    );
    static mut sudoers_subsystem_ids: [libc::c_uint; 0];
}

pub const EEXIST: libc::c_int = 17;

/*
 * Create any parent directories needed by path (but not path itself).
 * Note that path is modified but is restored before it returns.
 */
#[no_mangle]
pub fn sudo_mkdir_parents(
    mut path: *mut libc::c_char,
    mut uid: uid_t,
    mut gid: gid_t,
    mut mode: mode_t,
    mut quiet: bool,
) -> bool {
    let mut sb: stat = sb_all_arch;
    let mut slash: *mut libc::c_char = path;
    unsafe {
        debug_decl!(SUDOERS_DEBUG_UTIL!());

        /* cppcheck-suppress nullPointerRedundantCheck */
        'bad: loop {
            loop {
                slash = strchr(slash.offset(1_isize), '/' as i32);
                if slash.is_null() {
                    break;
                }
                *slash = '\0' as i32 as libc::c_char;
                sudo_debug_printf!(
                    SUDO_DEBUG_DEBUG | SUDO_DEBUG_LINENO,
                    b"mkdir %s, mode 0%o, uid %d, gid %d\0" as *const u8 as *const libc::c_char,
                    path,
                    mode,
                    uid as libc::c_int,
                    gid as libc::c_int
                );
                if mkdir(path, mode) == 0 as libc::c_int {
                    if uid != -(1 as libc::c_int) as uid_t
                        && gid != -(1 as libc::c_int) as gid_t
                        && chown(path, uid, gid) != 0 as libc::c_int
                    {
                        sudo_debug_printf!(
                            SUDO_DEBUG_ERROR | SUDO_DEBUG_ERRNO,
                            b"%s: unable to chown %d:%d %s\0" as *const u8 as *const libc::c_char,
                            get_function_name!(),
                            uid as libc::c_int,
                            gid as libc::c_int,
                            path
                        );
                    }

                    /*if uid != -(1 as libc::c_int) as uid_t && gid != -(1 as libc::c_int) as gid_t {
                        if chown(path, uid, gid) != 0 as libc::c_int {
                            sudo_debug_printf!(
                                SUDO_DEBUG_ERROR | SUDO_DEBUG_ERRNO,
                                b"%s: unable to chown %d:%d %s\0" as *const u8
                                    as *const libc::c_char,
                                get_function_name!(),
                                uid as libc::c_int,
                                gid as libc::c_int,
                                path
                            );
                        }
                    }*/
                } else {
                    if *__errno_location() != EEXIST {
                        if !quiet {
                            sudo_warn!(
                                b"unable to mkdir %s\0" as *const u8 as *const libc::c_char,
                                path
                            );
                        }
                        break 'bad;
                    }
                    /* Already exists, make sure it is a directory. */
                    if stat(path, &mut sb) != 0 as libc::c_int {
                        if !quiet {
                            sudo_warn!(
                                b"unable to stat %s\0" as *const u8 as *const libc::c_char,
                                path
                            );
                        }
                        break 'bad;
                    }
                    if !S_ISDIR!(sb.st_mode) {
                        if !quiet {
                            sudo_warn!(
                                b"%s exists but is not a directory (0%o)\0" as *const u8
                                    as *const libc::c_char,
                                path,
                                sb.st_mode
                            );
                        }
                        break 'bad;
                    }
                }
                *slash = '/' as i32 as libc::c_char;
            }

            debug_return_bool!(true);
        }
        //bad:
        /* We must restore the path before we return. */
        *slash = '/' as i32 as libc::c_char;
        debug_return_bool!(false);
    } //unsafe
}
